<?php 
class ControllerAccountOauth extends Controller {
	private $servers = null;
	
	public function __construct($registry, $route = '', $method = '') {
		parent::__construct($registry, $route, $method);
		
		$setting = C('social_login_module');
		
		if (!$setting) return;
		
		$this->servers = array(
			'Facebook' => array(
				'client_id'        => $setting[0]['Facebook_client_id'],
				'client_secret'    => $setting[0]['Facebook_client_secret'],
				'scope'            => 'email',
				'api'              => 'https://graph.facebook.com/me',
				'field'            => array(
										'id'        => 'sub',
										'email'     => 'email',
										'firstname' => 'first_name',
										'lastname'  => 'last_name'
				),
				'param'            => array(),
			),

			'Google' => array(
				'client_id'        => $setting[0]['Google_client_id'],
				'client_secret'    => $setting[0]['Google_client_secret'],
				'scope'            => 'https://www.googleapis.com/auth/userinfo.email '
									.'https://www.googleapis.com/auth/userinfo.profile',
				'api'              => 'https://www.googleapis.com/oauth2/v1/userinfo',
				'field'            => array(
										'id' => 'sub',
										'email' => 'email',
										'firstname' => 'given_name',
										'lastname' => 'family_name'
				),
				'param'           => array(),
			),
		);
	}
	
	public function index() {
		if ($this->customer->isLogged()) {
			$this->logined();
		}
		
		$server = G('s');
		if (!$server && isset($this->session->data['oauth_server'])) {
			$server = $this->session->data['oauth_server'];
		}
		
		if (!array_key_exists($server, $this->servers)) {
			echo 'ERROR:' . $this->_['error_server'];
			exit(0);
		}
		
		require(DIR_SYSTEM . 'vendor/oauth/http.php');
		require(DIR_SYSTEM . 'vendor/oauth/oauth_client.php');
		
		$client = new oauth_client_class;
		$client->debug = true;
		$client->debug_http = true;
		$client->server = $server;
		$client->redirect_uri = U('account/oauth');

		$client->client_id = $this->servers[$server]['client_id'];
		$client->client_secret = $this->servers[$server]['client_secret'];		
		$client->scope = $this->servers[$server]['scope'];
		$client->Initialize();
		
		$user = array();		
		
		if(($success = $client->Process())) {
			if(strlen($client->access_token)) {
				$success = $client->CallAPI(											
					$this->servers[$server]['api'], 
					'GET', $this->servers[$server]['param'],
					array('FailOnAccessError'=>true),$user);
			}
			
		}
		else {
			$this->log->write('ERROR: ' . $client->authorization_error);
			die('ERROR');
		}
		
		$success = $client->Finalize($success);
		
		if($client->exit) {
			$this->session->data['oauth_server'] = $server;
			exit(0);
		}
		
		if ($success) {
			$field = $this->servers[$server]['field'];
			$id = isset($user[$field['id']]) ? $user[$field['id']] : '';
			$email = isset($user[$field['email']]) ? $user[$field['email']] : '';
			$firstname = isset($user[$field['firstname']]) ? $user[$field['firstname']] : '';
			$lastname = isset($user[$field['lastname']]) ? $user[$field['lastname']] : '';
			if (!$id) die($this->_['error_no_id']);
			$this->checkLogin($server, $id, $email, $firstname, $lastname);
		}
		else {
			$this->log->write('ERROR: ' . $client->access_token_error);
			die('ERROR');
		}
	}
	
  	protected function checkLogin($server, $id, $email, $firstname, $lastname) {
			$_email = $this->db->queryOne("SELECT c.email FROM @@customer c JOIN @@customer_oauth co ON c.customer_id = co.customer_id AND  co.provider = '{$server}' WHERE co.id = '{$id}'");
			
			if (!$_email) {//not connect yet
				$_email = $email;		
				$customer = $this->db->queryOne("SELECT * FROM @@customer WHERE email = '{$email}'");
				if ($customer) { //registered
					$data = array('customer_id' => $customer['customer_id'],
								  'provider' => $server,
								  'id' => $id
							);
					$this->db->insert('customer_oauth', $data);
				}
				else {//new customer	
					$add_data = array();
					$add_data['email'] = $email;
					$add_data['password'] = $this->rand_string();
					$add_data['firstname'] = $firstname;
					$add_data['lastname'] = $lastname;
					$add_data['fax'] = '';
					$add_data['telephone'] = '';
					$add_data['company'] = '';
					$add_data['company_id'] = '';
					$add_data['tax_id'] = '';
					$add_data['address_1'] = '';
					$add_data['address_2'] = '';
					$add_data['city'] = '';
					$add_data['postcode'] = '';
					$add_data['country_id'] = 0;
					$add_data['zone_id'] = 0;
					
					M('account/customer');
					$customer_id = $this->model_account_customer->addCustomer($add_data);
					$data = array('customer_id' => $customer_id,
								  'provider' => $server,
								  'id' => $id
							);
					$this->db->insert('customer_oauth', $data);
				}
			}			
			
			if($this->customer->login($_email, null, true)){
				unset($this->session->data['guest']);
				$this->logined();
			}
	}
	
	private function rand_string($len = 8) {
		$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~%#@}{[]?,.';
		$str = '';
		for ($i=0; $i < $len; $i++)	{
			$str .= substr($chars, mt_rand(0, strlen($chars) -1), 1);
		}
		return $str;
	}
	
	private function logined() {
		echo '<script>if(opener) opener.window.oautho_login();window.close();</script>';
		exit(0);
	}
}